package com.jinbiao.quasar.scheduling.quartz;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.jinbiao.quasar.model.SysJobLog;
import com.jinbiao.quasar.scheduling.scheduled.JobHolder;
import com.jinbiao.quasar.service.JobService;
import org.noear.solon.Solon;
import org.noear.solon.core.handle.Context;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import java.util.Date;

/**
 * Quartz 任务执行代理
 *
 * @author noear
 * @since 1.11
 * @since 2.2
 * */
@DisallowConcurrentExecution
public class ConcurrentQuartzProxy implements Job {
    public static final String LOG_FORMAT = "任务【{}】，总耗时：{}毫秒";
    public static final String EXCEPTION_FORMAT = "任务【{}】，出现异常：{}";
    @Override
    public void execute(JobExecutionContext jc) throws JobExecutionException {
        JobService jobService = Solon.context().getBean(JobService.class);
        SysJobLog sysJobLog = new SysJobLog();
        String name = jc.getJobDetail().getKey().getName();
        JobHolder jobHolder = JobManager.getInstance().jobGet(name);
        sysJobLog.setJobName(jobHolder.getScheduled().nickName());
        sysJobLog.setJobInnerName(jobHolder.getScheduled().name());
        sysJobLog.setJobGroup(jobHolder.getScheduled().jobGroup());
        sysJobLog.setJobFireTime(DateUtil.date());
        sysJobLog.setJobNextFireTime(jc.getNextFireTime());
        long startTime = System.currentTimeMillis();
        if (jobHolder != null) {
            Context ctx = QuartzContext.getContext(jc);
            try {
                jobHolder.handle(ctx);
                long times = System.currentTimeMillis()-startTime;
                sysJobLog.setJobFireLog(StrUtil.format(LOG_FORMAT,sysJobLog.getJobName(),times));
            } catch (Throwable e) {
                sysJobLog.setJobFireException(StrUtil.format(EXCEPTION_FORMAT,sysJobLog.getJobName(),e.getStackTrace()));
                throw new JobExecutionException("Job execution failed: " + name, e);
            }finally {
                jobService.addJobLog(sysJobLog);
            }
        }
    }


}
